﻿using Foxit.PDF;
using Foxit.PDF.IO;
using Foxit.PDF.PageElements;
using Sustainalytics.Entities.RiskRatings;
using Sustainalytics.Reporting.Framework;
using System;
using System.Collections.Generic;


namespace Sustainalytics.RiskRatings.Reporting.Charts
{
    public enum RiskChartType
    {
        Overview,
        MEI
    }
    public class RiskRating_RiskAnalysisRangeChart : PageElement
    {
        public float Left { get; set; }
        public float Top { get; set; }
        public float Value { get; set; }
        public float SubIndustryValue { get; set; }
        public float FinalBetaFactor { get; set; }
        public float Width { get; set; }
        public float Height { get; set; }
        public string Type { get; set; }
        public RiskChartType ChartType { get; set; }
        public string Assessment { get; set; }
        public List<ExposureCluster> ExposureClusterList { get; set; }
        public List<ManagementCluster> ManagementClusterList { get; set; }

        private Group Elements()
        {
            var elements = new Group();
            var assessmentColors = new Dictionary<string, RgbColor>();
            float currentYOffset = Top;
            float startingPos;
            if (Type == "Exposure")
            {
                assessmentColors = new Dictionary<string, RgbColor>()
                    {
                        {"Low",  new RgbColor(204, 204, 204)},
                        {"Medium",  new RgbColor(249, 222, 148)},
                        {"High",  new RgbColor(246, 205, 92)},
                    };
            }
            if (Type == "Management")
            {
                assessmentColors = new Dictionary<string, RgbColor>()
                    {
                        {"Strong",  new RgbColor(204,204,204)},
                        {"Average",  new RgbColor(190,231,230)},
                        {"Weak",  new RgbColor(124, 208, 206)},
                    };
            }

            currentYOffset += 3f;

            currentYOffset += 10f;

            startingPos = Left;
            //switch case start
            switch (Type)
            {   case "Exposure":
                    if (Value == 0) Value += 0.01f;
                    foreach (var cluster in ExposureClusterList)
                    {
                        if (Value > cluster.UpperBound)
                        {
                            elements.Add(new Rectangle(startingPos, currentYOffset, 30f, 8f,
                                assessmentColors[cluster.Assessment.ToString()], assessmentColors[cluster.Assessment.ToString()]));
                        }
                        else if (Value > cluster.LowerBound && Value <= cluster.UpperBound)
                        {
                            elements.Add(new Rectangle(startingPos, currentYOffset, 30f, 8f,
                                RgbColor.Black, assessmentColors[cluster.Assessment.ToString()]));
                            startingPos += 1f;
                        }
            
                        else
                        {
                            elements.Add(new Rectangle(startingPos, currentYOffset, 30f, 8f,
                               RgbColor.LightGrey, RgbColor.White, 0.5f));
                        }

                        elements.Add(new Label(cluster.Assessment.ToString(),
                              startingPos,
                              currentYOffset - 25f,
                              30f,
                              7.5f, Fonts.RobotoRegular, 5.5f, TextAlign.Center, RgbColor.Black));
                        var plus = String.Empty;
                        if (ChartType == RiskChartType.MEI && (cluster.UpperBound == 100 || cluster.UpperBound==20))
                        {
                            plus = "+";
                            cluster.UpperBound = 20;
                        }

                        elements.Add(new Label($"{cluster.LowerBound}-{cluster.UpperBound}"+plus,
                                  startingPos + 3f,
                                  currentYOffset - 15f,
                                  25f,
                                  7.5f, Fonts.RobotoRegular, 5.5f, TextAlign.Center, RgbColor.Gray));
                       
                        

                        startingPos += 30f;
                    }

                    startingPos = Left;
                    var startingPosSubIndustryValue = Left;
                    var score = Math.Round(Value, 1);
                    foreach (var cluster in ExposureClusterList)
                    {
                        if (ChartType == RiskChartType.MEI && Type == "Exposure" && cluster.UpperBound == 100)
                            cluster.UpperBound = 20;
                        var boundDiff = cluster.UpperBound - cluster.LowerBound;
                        var scoreDiff = score - cluster.LowerBound;

                        var unit = 30 / boundDiff;

                        var increment = 0f;

                        if (score > cluster.UpperBound)
                        {
                            increment = (float)(unit * boundDiff);
                        }
                        else if (score > cluster.LowerBound && score <= cluster.UpperBound)
                        {
                            increment = (float)(unit * scoreDiff);
                        }

                        startingPos += increment;
                    }
                    if (SubIndustryValue != 0)
                    {
                        var subIndustryScore = Math.Round(SubIndustryValue, 1);
                        foreach (var cluster in ExposureClusterList)
                        {
                            if (ChartType == RiskChartType.MEI && cluster.UpperBound == 100)
                            {
                                cluster.UpperBound = 20;
                            }
                            var boundDiff = cluster.UpperBound - cluster.LowerBound;
                            var scoreDiff = subIndustryScore - cluster.LowerBound;

                            var unit = 30 / boundDiff;

                            var increment = 0f;

                            if (subIndustryScore > cluster.UpperBound)
                            {
                                increment = (float)(unit * boundDiff);
                            }
                            else if (subIndustryScore > cluster.LowerBound && subIndustryScore <= cluster.UpperBound)
                            {
                                increment = (float)(unit * scoreDiff);
                            }

                            startingPosSubIndustryValue += increment;
                        }
                        startingPosSubIndustryValue -= 3.5f;
                        var pathSubIndustry = new Path(startingPosSubIndustryValue, currentYOffset +14f, RgbColor.Black, RgbColor.Black, 0.5f, LineStyle.Solid, true);
                        pathSubIndustry.SubPaths.Add(new LineSubPath(startingPosSubIndustryValue + 6f, currentYOffset + 14f));
                        pathSubIndustry.SubPaths.Add(new LineSubPath(startingPosSubIndustryValue + 3f, currentYOffset +9f));

                        elements.Add(pathSubIndustry);
                        elements.Add(new Label("SubIndustry", startingPosSubIndustryValue , currentYOffset + 15f, 50f, 6, Fonts.RobotoBold,6, TextAlign.Left, RgbColor.Black));
                        //elements.Add(new Label("( Beta=" + FinalBetaFactor.ToString("0.00") + " )", startingPosSubIndustryValue, currentYOffset + 22f, 50f, 6, Fonts.RobotoRegular, 6, TextAlign.Left, RgbColor.Black));

                    }
                    break;
                case "Management":
                    if (Value == 0) Value += 0.01f;
                    var x = Left + 60f;
                    foreach (var cluster in ManagementClusterList)
                    {
                        if (Value > cluster.UpperBound)
                        {

                            elements.Add(new Rectangle(x, currentYOffset, 30f, 8f,
                               RgbColor.LightGrey, RgbColor.White, 0.5f));
                        }
                        else if (Value > cluster.LowerBound && Value <= cluster.UpperBound)
                        {
                            elements.Add(new Rectangle(x, currentYOffset, 30f, 8f,
                                RgbColor.Black, assessmentColors[cluster.Assessment.ToString()]));
                            x -= 0.5f;
                        }
                        else
                        {
                            elements.Add(new Rectangle(x, currentYOffset, 30f, 8f,
                                assessmentColors[cluster.Assessment.ToString()], assessmentColors[cluster.Assessment.ToString()]));
                        }

                        elements.Add(new Label(cluster.Assessment.ToString(),
                              x,
                              currentYOffset - 25f,
                              30f,
                              7.5f, Fonts.RobotoRegular, 5.5f, TextAlign.Center, RgbColor.Black));

                        elements.Add(new Label($"{cluster.UpperBound}-{cluster.LowerBound}",
                            x + 3f,
                            currentYOffset - 15f,
                            25f,
                            7.5f, Fonts.RobotoRegular, 5.5f, TextAlign.Center, RgbColor.Gray));

                        x -= 30f;

                        startingPos += 30;
                    }
                    score = Math.Round(Value, 1);

                    foreach (var cluster in ManagementClusterList)
                    {
                        var boundDiff = cluster.UpperBound - cluster.LowerBound;
                        var scoreDiff = score - cluster.LowerBound;

                        var unit = 30 / boundDiff;

                        var increment = 0f;

                        if (score > cluster.UpperBound)
                        {
                            increment = (float)(unit * boundDiff);
                        }
                        else if (score > cluster.LowerBound && score <= cluster.UpperBound)
                        {
                            increment = (float)(unit * scoreDiff);
                        }

                        startingPos -= increment;
                    }
                    break;

            }
            //switch case end

            var path = new Path(startingPos, currentYOffset - 2f, RgbColor.Black, RgbColor.Black, 0.5f, LineStyle.Solid, true);

            path.SubPaths.Add(new LineSubPath(startingPos - 3f, currentYOffset - 7f));
            path.SubPaths.Add(new LineSubPath(startingPos + 3f, currentYOffset - 7f));

            elements.Add(path);

            return elements;
        }

        public override void Draw(PageWriter writer)
        {
            var elements = Elements();
            writer.Write_q_(true);
            elements.Draw(writer);
            writer.Write_Q(true);
        }
    }
}
